package service_manager

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"sync"
	"time"
)

// ServiceState 服务状态
type ServiceState int

var serviceManagerInst *ServiceManager

const (
	ServiceStopped ServiceState = iota
	ServiceRunning
	ServiceFailed
	ServicePadding
)

const (
	serviceDataDir  = "data"
	serviceDataFile = serviceDataDir + "/services.json"
	serviceLogDir   = "logs"
	serviceLogFile  = serviceLogDir + "/service_errors.log"
)

// ServiceError 服务错误
type ServiceError struct {
	Time    time.Time `json:"time"`
	Message string    `json:"message"`
	Details string    `json:"details,omitempty"`
}

// Service 服务接口
type Service interface {
	GetName() string
	GetDescription() string
	// 服务生命周期管理
	OnStart(ctx context.Context) error // 启动前的初始化
	Entry(ctx context.Context) error   // 服务主入口
	OnStop(ctx context.Context) error  // 停止前的清理
	GetDependencies() []string         // 获取依赖的服务名列表
	// 错误处理
	GetLastError() *ServiceError // 获取最后一次错误
}

// ServiceInfo 服务信息
type ServiceInfo struct {
	Name         string        `json:"name"`
	Description  string        `json:"description"`
	Status       ServiceState  `json:"status"`
	LastError    *ServiceError `json:"lastError,omitempty"`
	Dependencies []string      `json:"dependencies,omitempty"`
}

// ServiceStates 服务状态集合，用于持久化
type ServiceStates struct {
	States map[string]ServiceState `json:"states"`
}

// ServiceInstance 服务实例
type ServiceInstance struct {
	service      Service
	ctx          context.Context
	cancel       context.CancelFunc
	status       ServiceState
	lastError    *ServiceError
	stopSignal   chan struct{}
	dependencies []string
}

// ServiceManager 服务管理器
type ServiceManager struct {
	services   map[string]*ServiceInstance
	mutex      sync.RWMutex
	statesFile string
	errLogFile string
	logger     *log.Logger
}

// 获取已经创建的服务管理器实例
func GetServiceManager() *ServiceManager {
	if serviceManagerInst == nil {
		serviceManagerInst = newServiceManager()
	}
	return serviceManagerInst
}

// NewServiceManager 创建服务管理器
func newServiceManager() *ServiceManager {
	if err := os.MkdirAll(serviceDataDir, 0755); err != nil {
		log.Fatalf("无法创建数据目录: %v", err)
	}
	// 创建日志目录
	if err := os.MkdirAll(serviceLogDir, 0755); err != nil {
		log.Fatalf("无法创建日志目录: %v", err)
	}
	// 创建服务管理器实例
	sm := &ServiceManager{
		services:   make(map[string]*ServiceInstance),
		statesFile: serviceDataFile,
		errLogFile: serviceLogFile,
	}

	// 初始化错误日志
	logFile, err := os.OpenFile(sm.errLogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Printf("无法创建错误日志文件: %v", err)
		sm.logger = log.New(os.Stderr, "[ServiceManager] ", log.LstdFlags)
	} else {
		sm.logger = log.New(logFile, "[ServiceManager] ", log.LstdFlags)
	}

	sm.loadStates()
	return sm
}

// RegisterService 注册服务
func (sm *ServiceManager) RegisterService(service Service) error {
	sm.mutex.Lock()
	defer sm.mutex.Unlock()

	name := service.GetName()
	if _, exists := sm.services[name]; exists {
		return fmt.Errorf("服务 %s 已经注册过了", name)
	}

	// 获取并验证依赖
	dependencies := service.GetDependencies()
	if err := sm.validateDependencies(name, dependencies); err != nil {
		return err
	}

	instance := &ServiceInstance{
		service:      service,
		status:       ServiceStopped,
		stopSignal:   make(chan struct{}),
		dependencies: dependencies,
	}
	sm.services[name] = instance

	// 从文件加载状态
	if state := sm.loadServiceState(name); state == ServiceRunning {
		go sm.StartService(name)
	}

	return nil
}

// validateDependencies 验证服务依赖关系
func (sm *ServiceManager) validateDependencies(serviceName string, dependencies []string) error {
	// 检查是否有循环依赖
	visited := make(map[string]bool)
	stack := make(map[string]bool)

	var checkCycle func(service string) error
	checkCycle = func(service string) error {
		if stack[service] {
			return fmt.Errorf("检测到循环依赖: %s", service)
		}
		if visited[service] {
			return nil
		}

		visited[service] = true
		stack[service] = true

		// 检查服务的依赖
		if instance, exists := sm.services[service]; exists {
			for _, dep := range instance.dependencies {
				if err := checkCycle(dep); err != nil {
					return err
				}
			}
		}

		stack[service] = false
		return nil
	}

	// 验证依赖服务是否存在
	for _, dep := range dependencies {
		if dep == serviceName {
			return fmt.Errorf("服务不能依赖自己: %s", serviceName)
		}
		if _, exists := sm.services[dep]; !exists {
			return fmt.Errorf("依赖的服务不存在: %s", dep)
		}
		if err := checkCycle(dep); err != nil {
			return err
		}
	}

	return nil
}

// StartService 启动服务
func (sm *ServiceManager) StartService(name string) error {
	sm.mutex.Lock()
	defer sm.mutex.Unlock()

	instance, exists := sm.services[name]
	if !exists {
		return fmt.Errorf("服务 %s 不存在", name)
	}

	if instance.status == ServiceRunning {
		return fmt.Errorf("服务 %s 已在运行中", name)
	}

	// 确保所有依赖服务都已启动
	for _, depName := range instance.dependencies {
		depInstance, exists := sm.services[depName]
		if !exists {
			return fmt.Errorf("依赖服务不存在: %s", depName)
		}
		if depInstance.status != ServiceRunning {
			return fmt.Errorf("依赖服务未运行: %s", depName)
		}
	}

	instance.status = ServicePadding

	// 重新初始化 stopSignal
	instance.stopSignal = make(chan struct{})

	// 创建新的上下文
	ctx, cancel := context.WithCancel(context.Background())
	instance.ctx = ctx
	instance.cancel = cancel

	// 启动服务协程
	go func() {
		defer func() {
			if r := recover(); r != nil {
				err := &ServiceError{
					Time:    time.Now(),
					Message: fmt.Sprintf("服务崩溃: %v", r),
				}
				instance.lastError = err
				instance.status = ServiceFailed
				sm.saveServiceState(name, ServiceFailed)
				sm.logError(name, err)
				close(instance.stopSignal)
			}
		}()

		// 调用 OnStart 回调
		if err := instance.service.OnStart(ctx); err != nil {
			instance.lastError = &ServiceError{
				Time:    time.Now(),
				Message: "启动初始化失败",
				Details: err.Error(),
			}
			instance.status = ServiceFailed
			sm.saveServiceState(name, ServiceFailed)
			sm.logError(name, instance.lastError)
			close(instance.stopSignal)
			return
		}

		instance.status = ServiceRunning
		sm.saveServiceState(name, ServiceRunning)

		// 调用服务入口函数
		if err := instance.service.Entry(ctx); err != nil {
			instance.lastError = &ServiceError{
				Time:    time.Now(),
				Message: "服务运行失败",
				Details: err.Error(),
			}
			instance.status = ServiceFailed
			sm.saveServiceState(name, ServiceFailed)
			sm.logError(name, instance.lastError)
		}

		// 服务正常退出或失败
		if instance.status != ServiceFailed {
			instance.status = ServiceStopped
			sm.saveServiceState(name, ServiceStopped)
		}

		// 发送停止信号
		close(instance.stopSignal)
	}()

	return nil
}

// StopService 停止服务
func (sm *ServiceManager) StopService(name string) error {
	sm.mutex.Lock()
	instance, exists := sm.services[name]
	if !exists {
		sm.mutex.Unlock()
		return fmt.Errorf("服务 %s 不存在", name)
	}

	if instance.status != ServiceRunning {
		sm.mutex.Unlock()
		return fmt.Errorf("服务 %s 未在运行", name)
	}

	// 检查是否有其他服务依赖此服务
	for _, otherInstance := range sm.services {
		if otherInstance.status == ServiceRunning {
			for _, dep := range otherInstance.dependencies {
				if dep == name {
					sm.mutex.Unlock()
					return fmt.Errorf("服务 %s 正在被其他运行中的服务依赖", name)
				}
			}
		}
	}

	// instance.status = ServicePadding

	// 取消context
	if instance.cancel != nil {
		instance.cancel()
	}
	sm.mutex.Unlock()

	// 调用 OnStop 回调
	if err := instance.service.OnStop(instance.ctx); err != nil {
		sm.logError(name, &ServiceError{
			Time:    time.Now(),
			Message: "停止清理失败",
			Details: err.Error(),
		})
	}

	// 等待服务完全停止
	<-instance.stopSignal
	return nil
}

// GetServiceStatus 获取服务状态
func (sm *ServiceManager) GetServiceStatus(name string) (ServiceState, error) {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	instance, exists := sm.services[name]
	if !exists {
		return ServiceStopped, fmt.Errorf("服务 %s 不存在", name)
	}

	return instance.status, nil
}

// ListServices 列出所有服务及其状态
func (sm *ServiceManager) ListServices() map[string]ServiceInfo {
	sm.mutex.RLock()
	defer sm.mutex.RUnlock()

	result := make(map[string]ServiceInfo)
	for name, instance := range sm.services {
		result[name] = ServiceInfo{
			Name:         name,
			Description:  instance.service.GetDescription(),
			Status:       instance.status,
			LastError:    instance.lastError,
			Dependencies: instance.dependencies,
		}
	}
	return result
}

// logError 记录错误到日志文件
func (sm *ServiceManager) logError(serviceName string, err *ServiceError) {
	if sm.logger != nil {
		sm.logger.Printf("服务 %s 错误: %s, 详情: %s",
			serviceName, err.Message, err.Details)
	}
}

// loadStates 从文件加载所有服务状态
func (sm *ServiceManager) loadStates() error {
	data, err := os.ReadFile(sm.statesFile)
	if err != nil {
		if os.IsNotExist(err) {
			states := ServiceStates{
				States: make(map[string]ServiceState),
			}
			return sm.saveStates(states)
		}
		return err
	}

	var states ServiceStates
	if err := json.Unmarshal(data, &states); err != nil {
		return err
	}

	return nil
}

// saveStates 保存所有服务状态到文件
func (sm *ServiceManager) saveStates(states ServiceStates) error {
	data, err := json.MarshalIndent(states, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(sm.statesFile, data, 0644)
}

// loadServiceState 加载单个服务的状态
func (sm *ServiceManager) loadServiceState(name string) ServiceState {
	data, err := os.ReadFile(sm.statesFile)
	// 默认状态不启动
	if err != nil {
		return ServiceStopped
	}

	var states ServiceStates
	if err := json.Unmarshal(data, &states); err != nil {
		return ServiceStopped
	}

	if state, exists := states.States[name]; exists {
		return state
	}
	return ServiceStopped
}

// saveServiceState 保存单个服务的状态
func (sm *ServiceManager) saveServiceState(name string, state ServiceState) error {
	data, err := os.ReadFile(sm.statesFile)
	if err != nil && !os.IsNotExist(err) {
		return err
	}

	var states ServiceStates
	if err == nil {
		if err := json.Unmarshal(data, &states); err != nil {
			return err
		}
	} else {
		states = ServiceStates{
			States: make(map[string]ServiceState),
		}
	}

	states.States[name] = state
	return sm.saveStates(states)
}
